package org.balthie.demo.sum.misc.direct;

import java.io.IOException;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryManagerMXBean;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.zip.Inflater;
import sun.misc.VM;


/*-XX:NativeMemoryTracking=detail -XX:MaxDirectMemorySize=10M*/
public class DirectMemoryTest
{
    private static BufferPoolMXBean bpMXBean;

    public static void main(String[] args) throws InterruptedException, IOException
    {
        initMXBeans();
        
        System.out.println(
                "BufferPoolMXBean Capacity = " + bpMXBean.getTotalCapacity() + " , MemoryUsed = " + bpMXBean.getMemoryUsed());
        
        System.out.println(
                " begin allocateDirect ");
        ByteBuffer buf = null;
        Inflater in = null;
        for(int i = 0; i < 1024; i++)
        {
            buf = ByteBuffer.allocateDirect(512 * 1024);
            TimeUnit.MILLISECONDS.sleep(20);
            if(i % 100 == 1)
            {
                DirectByteBufferPrinter.printBits();
            }
        }
        System.out.println(
                " end allocateDirect ");
        
        System.out.println(
                "BufferPoolMXBean Capacity = " + bpMXBean.getTotalCapacity() + " , MemoryUsed = " + bpMXBean.getMemoryUsed());
        
        DirectByteBufferPrinter.printBits();
        
        System.out.println("system gc");
        System.gc();
        
        TimeUnit.SECONDS.sleep(5L);
        
        DirectByteBufferPrinter.printBits();
        
        
        new URLClassPathResourcePrinter();
        
        TimeUnit.SECONDS.sleep(15000L);
    }

    private static void initMXBeans()
    {
        List<MemoryManagerMXBean> mmBeans = ManagementFactory.getMemoryManagerMXBeans();
        for(MemoryManagerMXBean mmBean : mmBeans)
        {
            System.out.println(mmBean.getName());
        }
        
        System.out.println("VM.maxDirectMemory : " + VM.maxDirectMemory());
        System.out.println("Runtime.maxMemory : " + Runtime.getRuntime().maxMemory());
        
        bpMXBean = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class).stream()
                .filter(b -> b.getName().equalsIgnoreCase("direct")).findFirst()
                .orElseThrow(null);
    }
    
}
